using UnityEngine;
using System.Collections;

public class Singleton<T> where T : class, new()
{
	private static T instance;
	
	public static T Instance
	{
		get
		{
			if (instance==null)
			{
				instance = new T();
			}
			return instance;
		}
	}
}

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
	private static T _instance;
	public static T Instance 
	{
		get
		{
			if (_instance == null)
			{
				CreateInstance();
			}
			
			return _instance;
		} 
	}
	
	public static GameObject CreateInstance()
	{
		GameObject go = new GameObject("_Singleton_" + typeof(T).ToString(), typeof(T));
		if (go)
		{
			_instance = go.GetComponent<T>();
			GameObject.DontDestroyOnLoad(go);
			
			if (_instance)
			{
				_instance.Init();
			}
		}
		
		return go;
	}
	
	public void _DummyCall() { }
	public static bool IsInstance() { return _instance != null; }
	public static void AccessInstance() { T ins = Instance; ins._DummyCall(); }
	public static void ClearInstance() { _instance = null; }
	public static void SetInstance(T ins) { _instance = ins; }
	public static void DestroyInstance()
	{
		if (_instance != null)
		{
			GameObject.DestroyImmediate(_instance.gameObject);
			_instance = null;
		}
	}
	
	
	public virtual void Init(){}
	
	private void OnApplicationQuit()
	{
		_instance = null;
	}
	
	void OnDestroy() { if (_instance == this) _instance = null; }
}

public abstract class MonoSingletonScene<T> : MonoBehaviour where T : MonoSingletonScene<T>
{
	private static T _instance;
	public static T Instance
	{
		get
		{
			if (_instance == null)
			{
				_instance = GameObject.FindObjectOfType(typeof(T)) as T;
				if (_instance == null)
				{
					GameObject go = new GameObject("_SingletonScene_" + typeof(T).ToString(), typeof(T));
					if (go)
					{
						_instance = go.GetComponent<T>();
					}
				}
				
				if (_instance)
				{
					_instance.Init();
				}
			}
			
			return _instance;
		}
	}
	
	public void _DummyCall() { }
	public static bool IsInstance() { return _instance != null; }
	public static void AccessInstance() { T ins = Instance; ins._DummyCall(); }
	
	public virtual void Init() { }
	
	private void OnApplicationQuit()
	{
		_instance = null;
	}
	
	void OnDestroy() { if (_instance == this) _instance = null; }
}